package resources;


import it.sauronsoftware.base64.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import utilities.Costanti;

import connectors.DBManager;
import connectors.VerbaliManager;
import entities.Verbale;


/*
 * Risorsa REST per la gestione dei Verbali
 * 
 * occorre fare un POST HTPP all'indirizzo http://91.226.109.144/GestioneMulteServer/verbale/aggiungi
 * per aggiungere un nuovo verbale di Multa nel DB
 */

@Path("/verbale")
public class VerbaleResource {
	
	static Logger logger = Logger.getLogger(VerbaleResource.class);
	
	private Verbale creaOggettoVerbale(JSONObject datiRicevuti,String numeroVerbale) throws Exception{
		//CREAZIONE DELL'OGGETTO VERBALE a partire dal JSONObject ricevuto
		Verbale verbale = new Verbale( numeroVerbale,
									   datiRicevuti.getString("data_ora"),
									   datiRicevuti.getString("luogoTrasgressione"),
									   datiRicevuti.getString("sottoscritti"),
									   datiRicevuti.getString("nome_cognome_trasgressore"),
									   datiRicevuti.getString("NascitaTrasgressore"),
									   datiRicevuti.getString("ProvNascitaTrasgr"),
									   datiRicevuti.getString("DataNascitaTrasgr"),
									   datiRicevuti.getString("residenzaTrasgr"),
									   datiRicevuti.getString("provResidenzaTrasgr"),
									   datiRicevuti.getString("documento"),
									   datiRicevuti.getString("nDocTrasgr"),
									   datiRicevuti.getString("documentoRilasciatoData"),
									   datiRicevuti.getString("documentoRilasciatoDa"),
									   datiRicevuti.getString("veicolo"),
									   datiRicevuti.getString("targa"),
									   datiRicevuti.getString("nome_cognome_possessore"),
									   datiRicevuti.getString("NascitaPossessore"),
									   datiRicevuti.getString("ProvNascitaPoss"),
									   datiRicevuti.getString("DataNascitaPoss"),
									   datiRicevuti.getString("residenzaPoss"),
									   datiRicevuti.getString("provResidenzaPoss"),
									   datiRicevuti.getString("violazioni"),
									   datiRicevuti.getString("dichiara"),																   
									   datiRicevuti.getDouble("sanzione"));
		
		//set campo foto
		String foto_encoded = datiRicevuti.getString("foto");
		if(foto_encoded != null && !foto_encoded.equals("")){
			logger.info("Richiesta di aggiungi Verbale ricevuta con numero verbale "+numeroVerbale
					+" con foto");
			InputStream inputStream = new ByteArrayInputStream(foto_encoded.getBytes("UTF-8"));
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			Base64.decode(inputStream, outputStream);
			verbale.setFoto(outputStream);
			outputStream.close();
			inputStream.close();
		}
		else{
			logger.info("Richiesta di aggiungi Verbale ricevuta con numero verbale "+numeroVerbale
					+" senza foto");
		}
		verbale.setLat(datiRicevuti.getDouble("lat"));
		verbale.setLongi(datiRicevuti.getDouble("longi"));
		return verbale;	
		
	}
	
	
	@POST @Path("/aggiungi")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_JSON)
	public JSONObject nuovoVerbale(JSONObject datiRicevuti){
		// 
		// codice per il calcolo tempo esecuzione
		//			
		long inizio = System.currentTimeMillis();
		long fine = 0;
		long inizioDB = 0;
		long fineDB = 0;
		////
		JSONObject jsonToReturn = new JSONObject();
      	DBManager dBmanager = null;
      	Connection con = null;
      	boolean errore = false;
      	Verbale verbale = null;
		String numeroVerbale = "";
      	String esito = "";
      	String matricola = "";
		String codice_agente = "";
		String imei = "";
      	
      //inizializzo i campi dell'oggetto JSON di risposta
      	try{
			jsonToReturn.put("esito_operazione", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			jsonToReturn.put("codice_errore","");
			jsonToReturn.put("info","");
			jsonToReturn.put("numero_verbale", "");
			jsonToReturn.put("tsFE",-1);
			jsonToReturn.put("tsBE",-1);
      		
      	}catch(JSONException je){}
      	
	    //parsing dei dati ricevuti
		try{
			matricola = datiRicevuti.getString("matricola_agente");
			codice_agente = datiRicevuti.getString("codice_agente");
			imei = datiRicevuti.getString("IMEI");
			numeroVerbale = datiRicevuti.getString("nverbale");
			if(numeroVerbale == null || numeroVerbale.equals("")){
				numeroVerbale = VerbaliManager.getNumeroVerbale();
			}
			verbale = creaOggettoVerbale(datiRicevuti, numeroVerbale);
			
		}catch(Exception e) {
			errore = true;
			try{
		      	jsonToReturn.put("codice_errore",Costanti.PARSING_DATA_ERROR);
		      	jsonToReturn.put("info","Errore nell'elaborazione dell'oggetto JSON ricevuto: "+e.getMessage());
			}catch(JSONException je){}
			
			logger.error("Errore nella elaborazione dell'oggetto JSON ricevuto: "+e.getMessage());
		}

		if(!errore){	
			//MEMORIZZAZIONE NEL DB DEL NUOVO VERBALE
			dBmanager = DBManager.getDBManager();
			if((con =dBmanager.connect())!=null){
				try{
					inizioDB = System.currentTimeMillis();//codice per il calcolo ts
					esito = dBmanager.storeVerbale(con,verbale,matricola,codice_agente,imei);
					fineDB = System.currentTimeMillis();//codice per il calcolo ts
				}
				catch(SQLException se) {
					errore = true;
					try{
				      	jsonToReturn.put("codice_errore",Costanti.SQL_ERROR);
				      	jsonToReturn.put("info","Errore nell'esecuzione della query SQL: "+se.getMessage());
					}catch(JSONException je){}
					logger.error("Errore nell'esecuzione della query SQL: "+se.getMessage());
				}
				catch(Exception ex){
					errore = true;
					try{
				      	jsonToReturn.put("codice_errore",Costanti.GENERIC_ERROR);
				      	jsonToReturn.put("info","Errore: "+ex.getMessage());
					}catch(JSONException je){}
					logger.error("Errore: "+ex.getMessage());
				}
				finally{
					if(dBmanager != null)	dBmanager.disconnect(con);
				}
			}
			else{
				errore = true;
				try{
			      	jsonToReturn.put("codice_errore",Costanti.DB_CONNECTION_ERROR);
			      	jsonToReturn.put("info","Errore nella connessione al DB server");
				}catch(JSONException e){}
		      	logger.error("Errore nella connessione al DB");
			}
			if(!esito.equals("Successo") && !errore){
				errore = true;
				try{
			      	jsonToReturn.put("esito_operazione", HttpServletResponse.SC_UNAUTHORIZED);
			      	if(esito.equals("Dispositivo non autorizzato")) jsonToReturn.put("codice_errore",Costanti.UNKNOWN_DEVICE);
			      	else jsonToReturn.put("codice_errore",Costanti.UNKNOWN_AGENT);
			      	jsonToReturn.put("info","Errore: "+esito);
				}catch(JSONException je){}
				logger.info("Operazione non valida: "+esito);				
			}
			if(esito.equals("Successo") && !errore){
				// 
				// codice per il calcolo tempo esecuzione
				//
				fine = System.currentTimeMillis();
				long tsBE = fineDB - inizioDB;
				long tsFE = fine - inizio - tsBE;
				try{
			      	jsonToReturn.put("esito_operazione", HttpServletResponse.SC_OK);
			      	jsonToReturn.put("numero_verbale", numeroVerbale);
			      	jsonToReturn.put("tsFE",tsFE);
			      	jsonToReturn.put("tsBE",tsBE);
				}catch(JSONException je){}
				
				logger.info("Il verbale con numero verbale "+numeroVerbale+" e' stato aggiunto correttamente");
			}
		}
		return jsonToReturn;

	}
	
	

}